package dbinit

import com.intellij.database.model.DasTable
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil

/*
 * Available context bindings:
 *   SELECTION   Iterable<DasObject>
 *   PROJECT     project
 *   FILES       files helper
 */


class Config {
    static baseProjectName = "equip"
    static projectName = "experiment"
//    static projectName = "auth"
    static basepackageName = "com.dm.cloud"
    static groovy.lang.GString projectBizBaseDir = "/${baseProjectName}-${projectName}-biz/src/main/java/io/cetc10/${baseProjectName}/${projectName}"
    static groovy.lang.GString projectCommonBaseDir = "/${baseProjectName}-${projectName}-common/src/main/java/io/cetc10/${baseProjectName}/${projectName}"
    static groovy.lang.GString projectBasePackage = "${basepackageName}.${projectName}"
}
//pojo
def pojoTool = new PojoTool()
//mapper
def mapperTool = new MapperTool()
//dto
def dtoTool = new DtoTool()
//查询对象
def searchTool=new SearchTool()
//查询请求包装体
def searchRequestTool=new SearchRequestTool()
//service
def serviceTool=new ServiceTool()
//service实现
def serviceImplTool=new ServiceImplTool()
//controller
def controllerTool=new ControllerTool()
FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable }.each {
        pojoTool.generate(it, dir)
        mapperTool.generate(it, dir)
        dtoTool.generate(it, dir)
        searchTool.generate(it, dir)
        searchRequestTool.generate(it, dir)
        serviceTool.generate(it, dir)
        serviceImplTool.generate(it, dir)
        controllerTool.generate(it, dir)
    }
}
/**
 * 实体模型
 */
class PojoTool {
    private basePackageName = Config.basepackageName
    private projectDir = "${Config.projectCommonBaseDir}/common/po";
    private typeMapping = [
            (~/(?i)int/)                      : "Integer",
            (~/(?i)float|double|decimal|real/): "Double",
            (~/(?i)datetime|timestamp/)       : "java.util.Date",
            (~/(?i)date/)                     : "java.util.Date",
            (~/(?i)time/)                     : "java.util.Date",
            (~/int/)                          : "Integer",
            (~/long/)                         : "Long",
            (~/(?i)/)                         : "String"
    ]

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        def parentFile = new File(dir.toString() + this.projectDir);

        if (!parentFile.exists()) {
            parentFile.mkdirs()
        }
        def fields = calcFields(table)
        new File(parentFile, className + ".java").withPrintWriter("UTF-8") { out -> generate(out, table, className, fields) }

    }

    def generate(out, table, className, fields) {
        out.println "package ${Config.projectBasePackage}.common.po;"
        out.println ""
        out.println "import ${basePackageName}.basepo.po.BasePo;\n" +
                "import lombok.AllArgsConstructor;\n" +
                "import lombok.Data;\n" +
                "import lombok.EqualsAndHashCode;\n" +
                "import lombok.NoArgsConstructor;\n" +
                "import lombok.experimental.SuperBuilder;\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n" +
                "import javax.persistence.Column;\n" +
                "import javax.persistence.Entity;\n" +
                "import javax.persistence.Table;"
        out.println ""
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type " + className + ".java\n" +
                "   * @desc ${className}\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println ""
        out.println "@Entity\n" +
                "@Data\n" +
                "@SuperBuilder\n" +
                "@NoArgsConstructor\n" +
                "@AllArgsConstructor\n" +
                "@Table(name = \"" + table.getName().toUpperCase().replaceAll(/^\d/, "") + "\")\n" +
                "@EqualsAndHashCode(callSuper = true)\n" +
                "@Schema(description = \"${className}\")"
        out.println "public class ${className} extends BasePo {"
        out.println ""
        fields.each() {
            if (it.name == "id" || it.name == "createTime" || it.name == "createUser" || it.name == "updateTime" || it.name == "updateUser") {
                // out.println ""
            } else {
                if (it.comm != "") out.println "      /** ${it.comm} **/ \n      @Schema(description = \"${it.comm}\")"
                if (it.annos != "") out.println "      ${it.annos}"
                out.println "      private ${it.type} ${it.name};"
            }

        }
        out.println ""
//  fields.each() {
//    out.println ""
//    out.println "  public ${it.type} get${it.name.capitalize()}() {"
//    out.println "    return ${it.name};"
//    out.println "  }"
//    out.println ""
//    out.println "  public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
//    out.println "    this.${it.name} = ${it.name};"
//    out.println "  }"
//    out.println ""
//  }
        out.println "}"
    }

    def calcFields(table) {
        DasUtil.getColumns(table).reduce([]) { fields, col ->
            def spec = Case.LOWER.apply(col.getDataType().getSpecification())
            def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
            fields += [[
                               name : javaName(col.getName(), false),
                               type : typeStr,
                               annos: "@Column(name = \"" + col.getName().toLowerCase() + "\")",
                               comm : col.getComment()]]
        }
    }

    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
                .replaceAll(/^\d/, "")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}


/**
 * mapper生成
 */
class MapperTool {
    private basePackageName = Config.basepackageName
    private projectDir = "${Config.projectBizBaseDir}/mapper";

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        def parentFile = new File(dir.toString() + this.projectDir);
        if (!parentFile.exists()) {
            parentFile.mkdirs()
        }
        new File(parentFile, className + "Mapper.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className) }
    }

    def generateContent(out, table, className) {
        out.println "package ${Config.projectBasePackage}.mapper;"
        out.println ""
        out.println "import ${basePackageName}.tkmybatis.service.BaseMapper;\n" +
                "import ${Config.projectBasePackage}.common.po.${className};\n" +
                "import org.apache.ibatis.annotations.*;"
        out.println ""
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type " + className + "Mapper.java\n" +
                "   * @desc ${className} mapper\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println ""
        out.println "@Mapper"
        out.println "public interface ${className}Mapper extends BaseMapper<${className}> {"
        out.println ""
        out.println ""
        out.println "}"
    }


    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceFirst("T", "").replaceAll(/^\d/, "")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }

}


/**
 * 通用dto生成
 */
class DtoTool {

    private basePackageName = Config.basepackageName
    private projectDir = "${Config.projectCommonBaseDir}/common/dto";
    private typeMapping = [
            (~/(?i)int/)                      : "Integer",
            (~/(?i)float|double|decimal|real/): "Double",
            (~/(?i)datetime|timestamp/)       : "java.util.Date",
            (~/(?i)date/)                     : "java.util.Date",
            (~/(?i)time/)                     : "java.util.Date",
            (~/int/)                          : "Integer",
            (~/long/)                         : "Long",
            (~/(?i)/)                         : "String"
    ]

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        //去掉前面的T
        className = className.substring(1)
        //第一个字符转换小写
//        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
//        def parentFile=new File(dir.toString()+this.projectDir+lastPackageName)
//        if(!parentFile.exists()){
//            parentFile.mkdirs()
//        }
        def parentFile = new File(dir.toString() + this.projectDir)
        if (!parentFile.exists()) {
            parentFile.mkdirs()
        }
        def fields = calcFields(table)
//        new File(parentFile, className + "DTO.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className, fields) }
        new File(parentFile, className + "DTO.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className, fields) }
    }

    def generateContent(out, table, className, fields) {
        //第一个字符转换小写
        def lastPackageName = className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.common.dto;\n"
        out.println "import ${basePackageName}.core.mode.BaseDTO;\n" +
                "import lombok.AllArgsConstructor;\n" +
                "import lombok.Data;\n" +
                "import lombok.Builder;\n" +
                "import lombok.NoArgsConstructor;\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;\n"
        out.println ""
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}DTO.java\n" +
                "   * @desc ${className}\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println ""
        out.println "@Data\n" +
                "@Builder\n" +
                "@NoArgsConstructor\n" +
                "@AllArgsConstructor\n" +
                "@Schema(description =\"${className} DTO\")"
        out.println "public class ${className}DTO extends BaseDTO {"
        out.println ""
        fields.each() {
            if (it.name == "id" || it.name == "createTime" || it.name == "createUser" || it.name == "updateTime" || it.name == "updateUser") {
                // out.println ""
            } else {
                if (it.comm != "") out.println "      /** ${it.comm} **/ \n      @Schema(description = \"${it.comm}\")"
                out.println "      private ${it.type} ${it.name};"
            }

        }
        out.println ""
        out.println "}"
    }

    def calcFields(table) {
        DasUtil.getColumns(table).reduce([]) { fields, col ->
            def spec = Case.LOWER.apply(col.getDataType().getSpecification())
            def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
            fields += [[
                               name: javaName(col.getName(), false),
                               type: typeStr,
                               comm: col.getComment()]]
        }
    }

    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/, "")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}


/**
 * 通用search生成
 */
class SearchTool{

    private basePackageName=Config.basepackageName
    private projectDir="${Config.projectCommonBaseDir}/common/request/";
    private typeMapping = [
            (~/(?i)int/)                      : "Integer",
            (~/(?i)float|double|decimal|real/): "Double",
            (~/(?i)datetime|timestamp/)       : "java.util.Date",
            (~/(?i)date/)                     : "java.util.Date",
            (~/(?i)time/)                     : "java.util.Date",
            (~/int/)                          : "Integer",
            (~/long/)                         : "Long",
            (~/(?i)/)                         : "String"
    ]
    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        //第一个字符转换小写
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        def parentFile=new File(dir.toString()+this.projectDir)
        if(!parentFile.exists()){
            parentFile.mkdirs()
        }
        def fields = calcFields(table)
        new File(parentFile, className + "PageSearch.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className, fields) }

    }

    def generateContent(out, table, className, fields) {
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.common.request;"
        out.println ""
        out.println "import com.dm.cloud.core.annotation.Orders;\n" +
                "import com.dm.cloud.core.annotation.Query;\n" +
                "import com.dm.cloud.core.mode.BaseSearchDTO;\n" +
                "import com.dm.cloud.core.enums.QueryEnum;\n" +
                "import lombok.AllArgsConstructor;\n" +
                "import lombok.Data;\n" +
                "import lombok.NoArgsConstructor;\n" +
                "import lombok.Builder;\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;"
        out.println ""
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}PageSearch.java\n" +
                "   * @desc ${className}\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println ""
        out.println "@Data\n" +
                "@NoArgsConstructor\n" +
                "@AllArgsConstructor\n" +
                "@Schema(description =\"${className} search\")"
        out.println "public class ${className}PageSearch extends BaseSearchDTO {"
        out.println ""
        fields.each() {
            if (it.name == "id" || it.name == "createTime" || it.name == "createUser" || it.name == "updateTime" || it.name == "updateUser") {
                // out.println ""
            } else {
                if (it.comm != "") out.println "      /** ${it.comm} **/ \n      @Schema(description = \"${it.comm}\")"
                out.println "      @Query(value = QueryEnum.EQ)"
                out.println "      private ${it.type} ${it.name};"
            }

        }
        out.println ""
        out.println "}"
    }

    def calcFields(table) {
        DasUtil.getColumns(table).reduce([]) { fields, col ->
            def spec = Case.LOWER.apply(col.getDataType().getSpecification())
            def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
            fields += [[
                               name : javaName(col.getName(), false),
                               type : typeStr,
                               comm : col.getComment()]]
        }
    }

    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/,"")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}

/**
 * 通用request生成
 */
class SearchRequestTool{

    private basePackageName=Config.basepackageName
    private projectDir="${Config.projectCommonBaseDir}/common/request/";

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        //第一个字符转换小写
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        def parentFile=new File(dir.toString()+this.projectDir)
        if(!parentFile.exists()){
            parentFile.mkdirs()
        }
        new File(parentFile, className + "SearchRequest.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className) }

    }

    def generateContent(out, table, className) {
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.common.request;"
        out.println ""
        out.println "import com.dm.cloud.core.mode.SearchRequestPage;\n" +
                "import lombok.*;\n" +
                "import io.swagger.v3.oas.annotations.media.Schema;"
        out.println ""
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}SearchRequest.java\n" +
                "   * @desc ${className}\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println ""
        out.println "@Data\n" +
                "@NoArgsConstructor\n" +
                "@Schema(description =\"${className}request\")"
        out.println "public class ${className}SearchRequest extends SearchRequestPage<${className}PageSearch> {"
        out.println ""
        out.println ""
        out.println "}"
    }


    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/,"")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}

/**
 * 生成Service接口
 */
class ServiceTool{

    private basePackageName=Config.basepackageName
    private projectDir="${Config.projectBizBaseDir}/service";

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        //第一个字符转换小写
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);

//        //生成mode目录
//        def modelParentFile=new File(dir.toString()+this.projectDir+lastPackageName+"/mode")
//        if(!modelParentFile.exists()){
//            modelParentFile.mkdirs()
//        }
        //生成service目录
        def parentFile=new File(dir.toString()+this.projectDir)
        if(!parentFile.exists()){
            parentFile.mkdirs()
        }
        new File(parentFile, className + "Service.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className) }

    }

    def generateContent(out, table, className) {
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.service;\n"
        out.println "import ${Config.projectBasePackage}.common.po.${className};\n" +
                "import com.dm.cloud.tkmybatis.service.BaseEntityService;\n" +
                "import ${Config.projectBasePackage}.common.request.${className}SearchRequest;\n"
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}Service.java\n" +
                "   * @desc ${className} service\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println "public interface ${className}Service extends BaseEntityService<${className}SearchRequest,${className}> {"
        out.println ""
        out.println ""
        out.println "}"
    }


    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/,"")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}

/**
 * 生成ServiceImpl类
 */
class ServiceImplTool{

    private basePackageName=Config.basepackageName
    private projectDir="${Config.projectBizBaseDir}/service/impl";

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        //第一个字符转换小写
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        def parentFile=new File(dir.toString()+this.projectDir)
        if(!parentFile.exists()){
            parentFile.mkdirs()
        }
        new File(parentFile, className + "ServiceImpl.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className) }

    }

    def generateContent(out, table, className) {

        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.service.impl;\n"
        out.println "import com.dm.cloud.tkmybatis.service.BaseMapper;\n" +
                "import ${Config.projectBasePackage}.mapper.${className}Mapper;\n" +
                "import ${Config.projectBasePackage}.service.${className}Service;\n" +
                "import ${Config.projectBasePackage}.common.po.${className};\n" +
                "import com.dm.cloud.core.exception.CustomException;\n" +
                "import org.springframework.beans.factory.annotation.Autowired;\n" +
                "import org.springframework.stereotype.Service;\n" +
                "import org.springframework.transaction.annotation.Transactional;\n"
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}ServiceImpl.java\n" +
                "   * @desc ${className} serviceImpl\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println "@Service\n"
        out.println "@Transactional\n"
        out.println "public class ${className}ServiceImpl implements ${className}Service {\n"
        out.println ""
        out.println "    @Autowired\n" +
                "    private ${className}Mapper ${lastPackageName}Mapper;\n"
        out.println ""
        out.println "    @Override\n" +
                "    public BaseMapper getMapper() {\n" +
                "        return ${lastPackageName}Mapper;\n" +
                "    }\n" +
                "    public void processBeforeOperation(${className} entity, BaseOperationEnum operationEnum) throws CustomException {\n" +
                "    }\n" +
                "\n" +
                "    public void processAfterOperation(${className} entity, BaseOperationEnum operationEnum) throws CustomException {\n" +
                "    }\n"
        out.println ""
        out.println "}"
    }


    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/,"")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}

/**
 * 生成controller类
 */
class ControllerTool{

    private basePackageName=Config.basepackageName
    private projectDir="${Config.projectBizBaseDir}/controller/defalut/";

    def generate(table, dir) {
        def className = javaName(table.getName(), true)
        className = className.substring(1) //去掉前面的T
        //第一个字符转换小写
        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        def parentFile=new File(dir.toString()+this.projectDir)
        if(!parentFile.exists()){
            parentFile.mkdirs()
        }
        new File(parentFile, className + "Controller.java").withPrintWriter("UTF-8") { out -> generateContent(out, table, className) }

    }

    def generateContent(out, table, className) {

        def lastPackageName=className.substring(0, 1).toLowerCase() + className.substring(1);
        out.println "package ${Config.projectBasePackage}.controller.defalut;\n\n" +
                "import com.dm.cloud.core.mode.ResultModel;\n" +
                "import com.dm.cloud.tkmybatis.service.BaseEntityService;\n" +
                "import com.dm.cloud.tkmybatis.service.EntityBaseController;\n" +
                "import io.swagger.v3.oas.annotations.tags.Tag;\n" +
                "import ${Config.projectBasePackage}.common.po.${className};\n" +
                "import ${Config.projectBasePackage}.common.dto.${className}DTO;\n" +
                "import ${Config.projectBasePackage}.common.request.${className}SearchRequest;\n" +
                "import ${Config.projectBasePackage}.service.${className}Service;\n" +
                "import org.springframework.beans.factory.annotation.Autowired;\n" +
                "import org.springframework.web.bind.annotation.*;\n" +
                "import java.util.List;\n"
        out.println "/**\n" +
                "   * @author hcx\n" +
                "   * @type ${className}Controller.java\n" +
                "   * @desc ${table.comment} ${className} controller\n" +
//          "   * @date 2020/10/9 11:10\n" +
                "   */"
        out.println "@RestController\n" +
                "@RequestMapping(\"/apis/v1/${lastPackageName}\")\n" +
                "@Tag(name =  \"${table.comment}  ${className}controller\")\n"
        out.println "public class ${className}Controller extends EntityBaseController<${className}SearchRequest, ${className}, ${className}DTO> {\n"
        out.println "\n" +
                "    @Autowired\n" +
                "    private ${className}Service ${lastPackageName}Service;\n" +
                "    @Override\n" +
                "    public ${className} getEntity() {\n" +
                "        return new ${className}();\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public ${className}DTO getDTO() {\n" +
                "        return new ${className}DTO();\n" +
                "    }\n" +
                "    @Override\n" +
                "    public BaseEntityService<${className}SearchRequest, ${className}> getService() {\n" +
                "        return ${lastPackageName}Service;\n" +
                "    }\n" +
                "\n"
        out.println "}"
    }


    def javaName(str, capitalize) {
        def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
                .collect { Case.LOWER.apply(it).capitalize() }
                .join("")
                .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_").replaceAll(/^\d/,"")
        capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
    }
}

